//
//  WNAudioManager.swift
//  WalkNovel
//
//  Created by Kevin on 2023/10/29.
//

import UIKit
import AVFoundation

//MARK: - 本地音乐
class WNAudioManager: NSObject, AVAudioPlayerDelegate {
    
    static let shared = WNAudioManager()
    
    let session = AVAudioSession.sharedInstance()

    var locationPlayer: AVAudioPlayer?
    
    func playLocationMusic(_ path: String, _ rate: Float = 1, _ time: TimeInterval = 0) {
        guard !isBlank(path) else {
            return
        }
        locationPlayer?.stop()
        do {
            try session.setCategory(.playback)
            try session.setActive(true)
            
            let url = NSURL(fileURLWithPath: path)
            locationPlayer = try AVAudioPlayer(contentsOf: (url as NSURL) as URL)
            locationPlayer?.delegate = self
            locationPlayer?.enableRate = true
            locationPlayer?.rate = rate
            locationPlayer?.currentTime = time
            locationPlayer?.numberOfLoops = 0
            locationPlayer?.prepareToPlay()
            locationPlayer?.play()
        }catch {
            WNHUD.wn_show("Play failed")
        }
    }
    
    // 暂停当前歌曲
    func pauseLocationMusic() -> () {
        locationPlayer?.pause()
    }
    
    // 继续播放当前歌曲
    func resumeLocationMusic(_ rate: Float = 1) -> () {
        locationPlayer?.rate = rate
        locationPlayer?.play()
    }
    
    // 停止播放当前歌曲
    func stopLocationMusic() -> () {
        locationPlayer?.stop()
        locationPlayer = nil
    }
    
    // 播放到指定时间
    func seekToTime(time: TimeInterval) -> () {
        locationPlayer?.currentTime = time
    }
    
    // 获得当前的时间
    func getCurrentTime() -> Float {
        guard locationPlayer != nil else {
            return 0
        }
        return Float((locationPlayer?.currentTime)!)
    }
    
    func audioPlayerDidFinishPlaying(_ player: AVAudioPlayer, successfully flag: Bool) {
        WNHUD.wn_show("Play end")
        stopLocationMusic()
    }
    
    //MARK: - 网络音乐
    var palyerItem: AVPlayerItem?
    
    var networkPlayer: AVPlayer?
    
    func playNetworkMusic(_ urlString: String, _ rate: Float = 1) {
        guard !isBlank(urlString) else {
            return
        }
        guard let url = URL(string: urlString) else {
            return
        }
        removeObserver()
        if networkPlayer != nil {
            networkPlayer?.pause()
            networkPlayer = nil
            palyerItem = nil
        }
        palyerItem = AVPlayerItem(url: url)
        networkPlayer = AVPlayer.init(playerItem: palyerItem)
        networkPlayer?.rate = rate
        addObserver()
    }
    
    func pauseNetworkMusic() {
        networkPlayer?.pause()
    }
    
    func resumeNetworkMusic() {
        networkPlayer?.play()
    }
    
    func stopNetworkMusic() {
        networkPlayer?.pause()
        networkPlayer = nil
        palyerItem = nil
    }
    
    override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
        guard let playerItem = object as? AVPlayerItem else { return }
        if keyPath == "loadedTimeRanges" {
            // 缓冲进度 暂时不处理
        } else if keyPath == "status" {
            // 监听状态改变
            if playerItem.status == .readyToPlay {
                // 只有在这个状态下才能播放
                networkPlayer?.play()
            } else {
                WNHUD.wn_show("Play failed")
            }
        }
    }
    
    @objc func playCompletion() {
        WNHUD.wn_show("Play end")
    }
    
    func addObserver() {
        palyerItem?.addObserver(self, forKeyPath: "status", options: NSKeyValueObservingOptions.new, context: nil)
        NotificationCenter.default.addObserver(self, selector: #selector(playCompletion), name: .AVPlayerItemDidPlayToEndTime, object: nil)
    }
    
    func removeObserver() {
        palyerItem?.removeObserver(self, forKeyPath: "status")
        NotificationCenter.default.removeObserver(self, name: .AVPlayerItemDidPlayToEndTime, object: nil)
    }
}
